﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Newtonsoft.Json.Linq;

namespace DCT.Huiteng.Utility.Config
{
    public class JsonConfigParser : IConfigParser
    {
        private JObject jobject;

        public JsonConfigParser()
        {
            jobject = new JObject();
        }

        public IConfigParser Load(object config)
        {
            if (config == null || !(config is string))
            {
                throw new ArgumentException("config不能为空，且必须为字符串");
            }
            jobject = JObject.Parse(config.ToString());
            return this;
        }

        public IConfigParser Clear()
        {
            jobject = new JObject();
            return this;
        }

        public string ParseToString()
        {
            return jobject.ToString();
        }

        public IEnumerable<KeyValuePair<string, string>> GetKV(string key)
        {
            var property = jobject[key];
            if (property != null)
            {
                foreach (var item in property)
                {
                    if (item.Type == JTokenType.Property)
                    {
                        JProperty jp = (JProperty)item;
                        yield return new KeyValuePair<string, string>(jp.Name, jp.Value.ToString());
                    }
                }
            }
        }

        public IEnumerable<IEnumerable<KeyValuePair<string, string>>> GetListKV(string key)
        {
            JToken listProperty = jobject[key];
            if (listProperty != null)
            {
                var objects = (from o in listProperty
                              select o);

                foreach (var obj in objects)
                {
                    List<KeyValuePair<string, string>> objKV = new List<KeyValuePair<string, string>>();
                    foreach (var item in obj)
                    {
                        if (item.Type == JTokenType.Property)
                        {
                            JProperty jp = (JProperty)item;
                            objKV.Add(new KeyValuePair<string, string>(jp.Name, jp.Value.ToString()));
                        }
                    }
                    yield return objKV;
                }
            }
        }

        public IEnumerable<string> GetListVal(string key)
        {
            JToken listProperty = jobject[key];
            if (listProperty != null)
            {
                foreach (var item in listProperty)
                {
                    yield return item.ToString();
                }
            }
        }

        public string GetVal(string key, string defaultVal)
        {
            JToken jtoken = jobject[key];
            if (jtoken != null)
            {
                return jtoken.ToString();
            }
            return defaultVal;
        }

        public void SetKV(string key, IEnumerable<KeyValuePair<string, string>> kv)
        {
            JObject jkv = new JObject();
            foreach (var item in kv)
            {
                jkv.Add(new JProperty(item.Key, item.Value));
            }
            this.jobject[key] = jkv;
        }

        public void SetListKV(string key, IEnumerable<IEnumerable<KeyValuePair<string, string>>> kvList)
        {
            JArray jarray = new JArray();
            foreach (var kv in kvList)
            {
                JObject jkv = new JObject();
                foreach (var item in kv)
                {
                    jkv.Add(new JProperty(item.Key, item.Value));
                }
                jarray.Add(jkv);
            }
            this.jobject[key] = jarray;
        }

        public void SetListVal(string key, IEnumerable<string> listVal)
        {
            JArray jarray = new JArray(listVal.ToArray());
            this.jobject[key] = jarray;
        }

        public void SetVal(string key, string val)
        {
            this.jobject[key] = new JValue(val);
        }
    }
}
